/*
 * Copyright 2012 The LoadTestAnalyzer Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.yantsu.loadtestanalyzer.ltaimporter.importers;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import java.util.StringTokenizer;

public class Grinder implements Importer {
	private String testName;
	private BufferedReader reader;
	private int lineNo;
	
	@Override
	public String getMapping() {
		return "{\"data_Grinder\" : {" +
				"\"_parent\" : {\"type\" : \"series\"}," +
				"\"properties\" : {" +
					"\"timestamp\" : {\"type\" : \"date\"}," +
					"\"category\" : {\"type\" : \"string\", \"index\" : \"not_analyzed\"}," +
					"\"hostname\" : {\"type\" : \"string\", \"index\" : \"not_analyzed\"}" +
				"}" +
			"}" +
		"}";
	}

	@Override
	public void initialize(String testName, InputStream in) {
		this.testName = testName;
		reader = new BufferedReader(new InputStreamReader(in));
		lineNo = 0;
	}

	@Override
	public String getTestname() {
		return testName;
	}

	@Override
	public Data next() {
		Data data = null;
		try {
			String 	line = reader.readLine();
			if(lineNo == 0) { //ignore header
				line = reader.readLine();
				lineNo++;
			}
			if(line != null) {
				data = new Data();
				data.hostname = "N/A";
				StringTokenizer tokenizer = new StringTokenizer(line, ", ");
				if(tokenizer.countTokens() != 12) {
					throw new IllegalStateException("Format error in Grinder data file in line " + lineNo);
				}
				String thread = tokenizer.nextToken();
				String run = tokenizer.nextToken();
				String test = tokenizer.nextToken();
				data.category = test;
				data.properties.put("thread", thread);
				data.properties.put("run", run);
				
				//validation and typing
				String timestamp = tokenizer.nextToken();
				long timestampL = -1;
				try {
					timestampL = Long.valueOf(timestamp);
				} catch(NumberFormatException e) {
					throw new IllegalStateException("Timestamp retrieved in line "+ lineNo + " is not a number, was " + timestamp, e);
				}
				data.timestamp = timestampL;
				
				putValue(data, tokenizer.nextToken(), "testtime");
				putValue(data, tokenizer.nextToken(), "errors");
				putValue(data, tokenizer.nextToken(), "responsecode");
				putValue(data, tokenizer.nextToken(), "responselength");
				putValue(data, tokenizer.nextToken(), "responseerrors");
				putValue(data, tokenizer.nextToken(), "ttrh");
				putValue(data, tokenizer.nextToken(), "ttec");
				putValue(data, tokenizer.nextToken(), "ttfb");

				lineNo++;
			}
		} catch (IOException e) {
			throw new IllegalStateException("Error in Grinder data file in line " + lineNo);
		}
		return data;
	}

	private void putValue(Data data, String dataStr, String name) {
		double doubleD = 0.0;
		try {
			NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
			doubleD = nf.parse(dataStr).doubleValue();
		} catch(NumberFormatException e) {
			throw new IllegalStateException(name + " retrieved in line " + lineNo + " is not a number, was " + dataStr, e);
		} catch (ParseException e) {
			throw new IllegalStateException(name + " retrieved in line " + lineNo + " is not a number, was " + dataStr, e);
		}
		data.values.put(name, doubleD);
	}
}
